home *** CD-ROM | disk | FTP | other *** search
/ Nebula 2 / Nebula Two.iso / SourceCode / MiscKit1.7.1 / MiscKit / Source / MiscGISKit / MiscMathCoordConverter.m < prev    next >
Text File  |  1995-07-08  |  6KB  |  180 lines

  1. /*======================= MiscMathCoordConverter.m ==========================*/
  2. /* MiscMathCoordConverter class converts between various standard
  3.    Mathematical coordinate systems. All values are double precision floating
  4.    point numbers representing locations in a three dimensional coordinate 
  5.    system.
  6.  
  7.    There is only one instance ever, so unless changes are made, this class
  8.    is NON REENTRANT.
  9.  
  10.    DMA Release 0.8, Copyright @1993 by Genesis Project, Ltd. All Rights
  11.    Reserved. For further information on terms and conditions see
  12.         the MiscKit license.
  13.  
  14. HISTORY
  15. 10-Mar-93  Dale Amon at GPL
  16.        Created.
  17. */
  18.  
  19. #import <ansi/math.h>
  20. #import <misckit/miscgiskit.h>
  21.  
  22. @implementation MiscMathCoordConverter
  23.  
  24. /*===========================================================================*/
  25. /* Internal methods
  26.    These are applied to each data point by a applyTransform:
  27. */
  28. /*===========================================================================*/
  29. /* Internal methods to convert a point to a different coordinate system.
  30.    Input vector is pointed to by src and the result of the transformation
  31.    is stored in dst.
  32. */
  33.  
  34. - (void) cartesianToCylindrical
  35.   {    dst[MISC_THETA_CYL]  = atan(src[MISC_Y_COORD]/src[MISC_X_COORD]);
  36.     dst[MISC_RADIUS_CYL]    = sqrt(src[MISC_X_COORD] * src[MISC_X_COORD] +
  37.                    src[MISC_Y_COORD] * src[MISC_Y_COORD]);
  38.     dst[MISC_Z_CYL]    = src[MISC_Z_COORD];
  39.   }
  40.  
  41. - (void) sphericalToCylindrical
  42.   {    dst[MISC_THETA_CYL]    = src[MISC_THETA_SPHERE];
  43.     dst[MISC_RADIUS_CYL]    = src[MISC_RHO_SPHERE] * sin(src[MISC_PHI_SPHERE]);
  44.     dst[MISC_Z_CYL]    = src[MISC_RHO_SPHERE] * cos(src[MISC_PHI_SPHERE]);
  45.   }
  46.  
  47. - (void) cartesianToSpherical
  48.   {    double    xsq,ysq;
  49.  
  50.     xsq = src[MISC_X_COORD] * src[MISC_X_COORD];
  51.     ysq = src[MISC_Y_COORD] * src[MISC_Y_COORD];
  52.  
  53.     dst[MISC_RHO_SPHERE]   = sqrt(xsq + ysq +
  54.             src[MISC_Z_COORD] * src[MISC_Z_COORD]);
  55.     dst[MISC_THETA_SPHERE] = atan(src[MISC_Y_COORD]/src[MISC_X_COORD]);
  56.     dst[MISC_PHI_SPHERE]   = atan(sqrt(xsq + ysq)/src[MISC_Z_COORD]);
  57.   }
  58.  
  59. - (void) cylindricalToSpherical
  60.   {    dst[MISC_RHO_SPHERE]   = sqrt(src[MISC_RADIUS_CYL] * src[MISC_RADIUS_CYL] +
  61.                  src[MISC_Z_CYL] * src[MISC_Z_CYL]);
  62.     dst[MISC_THETA_SPHERE] = src[MISC_THETA_CYL];
  63.     dst[MISC_PHI_SPHERE]   = atan(src[MISC_RADIUS_CYL]/src[MISC_Z_CYL]);
  64.   }
  65.  
  66. - (void) cylindricalToCartesian
  67.   {    dst[MISC_X_COORD] = src[MISC_RADIUS_CYL] * cos(src[MISC_THETA_CYL]);
  68.     dst[MISC_Y_COORD] = src[MISC_RADIUS_CYL] * sin(src[MISC_THETA_CYL]);
  69.     dst[MISC_Z_COORD] = src[MISC_Z_CYL];
  70.   }
  71.  
  72. - (void) sphericalToCartesian
  73.   {    dst[MISC_X_COORD] = src[MISC_RHO_SPHERE] * sin(src[MISC_PHI_SPHERE]) * 
  74.             cos(src[MISC_THETA_CYL]);
  75.     dst[MISC_Y_COORD] = src[MISC_RHO_SPHERE] * sin(src[MISC_PHI_SPHERE]) *
  76.             sin(src[MISC_THETA_CYL]);
  77.     dst[MISC_Z_COORD] = src[MISC_RHO_SPHERE] * cos(src[MISC_PHI_SPHERE]);
  78.   }
  79.  
  80. /*===========================================================================*/
  81. /* Class methods */
  82. /*===========================================================================*/
  83. /* Only one converter of this type is every needed. Of course if we got
  84.    into a really big multiprocess agora system there might be a case
  85.    for multiple converters. Since this object is shared by many, it
  86.    doesn't particularly matter what zone it is allocated from.
  87. */
  88.  
  89. static id theMathCoordConverter = nil;
  90.  
  91. + new
  92. {
  93.     if (!theMathCoordConverter) theMathCoordConverter = [[super alloc] init];
  94.     return theMathCoordConverter;
  95. }
  96.  
  97.  
  98. /*---------------------------------------------------------------------------*/
  99. /* Since there is only one object needed, alloc and allocFromZone: are 
  100.    disabled and considered errors. free is simply overridden and made into a
  101.    no op.
  102. */
  103.  
  104. +alloc 
  105.  {    [self error:"  %s class should not be sent '%s' messages\n",
  106.             [[self class] name], sel_getName(_cmd)];
  107.     return self;
  108.  }
  109.  
  110. +allocFromZone: (NXZone *)zone
  111.  {    [self error:"  %s class should not be sent '%s' messages\n",
  112.             [[self class] name], sel_getName(_cmd)];
  113.     return self;
  114.  }
  115.  
  116.  
  117. - free {return self;}
  118.  
  119.  
  120. /*===========================================================================*/
  121. /* Initialization methods */
  122. /*===========================================================================*/
  123. /* We add a list of all the services which we are able to provide.
  124.    Note that there is only one PlanetCoordConverter ever created. Once 
  125.    initialized the same object is given to all comers and can not be destroyed.
  126. */
  127.  
  128. - init
  129.   {    Class    sphere,cylinder,cartesian;
  130.  
  131.     [super init];
  132.  
  133.     sphere    = [MiscSphericalCoord   class];
  134.     cylinder  = [MiscCylindricalCoord class];
  135.        cartesian = [MiscCartesianCoord   class];
  136.  
  137.     [self addService: @selector(cartesianToCylindrical)
  138.       convertsFrom: cartesian to: cylinder]; 
  139.  
  140.     [self addService: @selector(sphericalToCylindrical)
  141.       convertsFrom: sphere    to: cylinder]; 
  142.  
  143.     [self addService: @selector(cartesianToSpherical)
  144.       convertsFrom: cartesian to: sphere]; 
  145.  
  146.     [self addService: @selector(cylindricalToSpherical)
  147.       convertsFrom: cylinder  to: sphere];
  148.  
  149.     [self addService: @selector(cylindricalToCartesian)
  150.       convertsFrom: cylinder  to: cartesian];
  151.  
  152.     [self addService: @selector(sphericalToCartesian)
  153.       convertsFrom: sphere    to: cartesian];
  154.  
  155.     [self addService: [self fastCopySelector]
  156.       convertsFrom: sphere    to: sphere];
  157.  
  158.     [self addService: [self fastCopySelector]
  159.       convertsFrom: cylinder  to: cylinder];
  160.  
  161.     [self addService: [self fastCopySelector]
  162.       convertsFrom: cartesian to: cartesian];
  163.  
  164.     return self;
  165.   }
  166.  
  167.  
  168. /*===========================================================================*/
  169. /* Archive methods */
  170. /*===========================================================================*/
  171.  
  172. - finishUnarchiving
  173. {
  174.     [self free];
  175.     return [MiscMathCoordConverter new];
  176. }
  177.  
  178.  
  179. @end
  180.